package se.webbzon.oschi01.nbt;

import java.util.ArrayList;
import java.util.Collection;

import se.webbzon.oschi01.nbt.TagEvent.Action;

abstract class AbstractTag<T> implements Tag<T> {
	
	private TagSibling sibling = null;
	private final TagFactory<T> factory;
	private String tagName;
	private Collection<TagListener> listeners = null;
	
	protected AbstractTag(TagFactory<T> factory) {
		this(factory, null);
	}
	
	protected AbstractTag(TagFactory<T> factory, String tagName) {
		this.factory = factory;
		this.tagName = tagName == null || tagName.isEmpty() ? null : tagName;
	}
	
	@Override public final void setName(String name) {
		this.tagName = name == null || name.isEmpty() ? null : name;
		broadcastEvent(new TagEvent(this,Action.RENAMED,name));
	}
	
	@Override public boolean canAdopt(Tag<?> child) {
		return false;
	}
	
	@Override public abstract AbstractTag<T> clone();

	@Override public final String toString() {
		if (tagName == null)
			return "";
		else
			return tagName;
	}
	
	@Override public TagFactory<T> getFactory() {
		return factory;
	}
	
	@Override public boolean hasChildren() {
		return false;
	}

	@Override public TagGeneration<?> getChildren() {
		return null;
	}

	@Override public void addListener(TagListener listener) {
		if (listeners == null)
			listeners = new ArrayList<TagListener>();
		listeners.add(listener);
	}

	@Override public void removeListener(TagListener listener) {
		if (listeners != null) {
			listeners.remove(listener);
			if (listeners.isEmpty())
				listeners = null;
		}
	}

	@Override public boolean hasParent() {
		if (sibling == null)
			return false;
		else
			return sibling.hasParent();
	}

	@Override public void setSibling(TagSibling sibling) {
		this.sibling = sibling;
	}

	@Override public Tag<?> getParent() {
		return sibling.getParent();
	}

	@Override public TagSibling getSibling() {
		return sibling;
	}
	
	@Override public TagGeneration<?> getGeneration() {
		return sibling.getGeneration();
	}

	@Override public void broadcastEvent(TagEvent event) {
		if (listeners != null) {
			TagListener[] type = new TagListener[0];
			for (TagListener listener : listeners.toArray(type)) {
				listener.onTagEvent(event);
			}
		}
		if (hasParent()) {
			getParent().broadcastEvent(event);
		}
	}
	
}
